<script setup lang="tsx">
import { computed, reactive, watch } from 'vue';
import { NTag } from 'naive-ui';
import SvgIcon from '@/components/custom/svg-icon.vue';
import { fetchVPNDetail } from '@/service/api';

defineOptions({
  name: 'VPNDetail'
});

interface Props {
  id: TicketManageApi.VPNManage.VPN['id'];
}

const { id } = defineProps<Props>();
/** 加解密流量信息 */
const ipsecStatusInfo = reactive<TicketManageApi.VPNManage.VPNDetail>(initStatusInfo());

const networkSegment = computed(() => {
  if (ipsecStatusInfo.deviceList.length === 0) return null;
  return (
    <div class="mt-5px w-full flex flex-shrink-0 flex-grow-0 gap-16px">
      <div class="flex-col">
        <span class="w-full truncate">{ipsecStatusInfo.deviceList[0]?.deviceCity}</span>
        <span>{ipsecStatusInfo.deviceList[0]?.protectedSubnet}</span>
      </div>
      <SvgIcon local-icon="material-symbols-arrow-range" class="mt-12px text-icon text-success" />
      <div class="flex-col">
        <span class="w-full truncate">{ipsecStatusInfo.deviceList[1]?.deviceCity}</span>
        <span>{ipsecStatusInfo.deviceList[1]?.protectedSubnet}</span>
      </div>
    </div>
  );
});

const RxBytes = computed(() => {
  return formatBytes(ipsecStatusInfo.status.RxBytes);
});

const TxBytes = computed(() => {
  return formatBytes(ipsecStatusInfo.status.TxBytes);
});

function formatBytes(bytes: number) {
  if (typeof bytes !== 'number') return '-';
  if (bytes <= 0) return '0 B';

  const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
  const i = Math.floor(Math.log(bytes) / Math.log(1024));

  return `${(bytes / 1024 ** i).toFixed(2)} ${sizes[i]}`;
}

const visible = defineModel<boolean>('visible', {
  default: false
});

function initStatusInfo(): TicketManageApi.VPNManage.VPNDetail {
  return {
    deviceList: [],
    templateName: '',
    status: {
      RxBytes: 0,
      TxBytes: 0,
      State: null
    }
  };
}

const handleInitModel = async () => {
  Object.assign(ipsecStatusInfo, initStatusInfo());

  const { data: info, error } = await fetchVPNDetail(id);
  if (error) return;
  Object.assign(ipsecStatusInfo, info);
};

watch(visible, () => {
  if (visible.value) {
    handleInitModel();
  }
});
</script>

<template>
  <NModal v-model:show="visible" title="量子加密隧道" preset="card" class="w-600px">
    <NScrollbar trigger="none" content-class="max-h-500px">
      <NForm label-placement="left" :label-width="100" :show-feedback="false" class="vpnDetailForm p-t-20px">
        <div class="mb-12px text-16px font-bold">量子隧道配置</div>
        <NGrid :cols="1">
          <NFormItemGi label="关联模板：" class="pr-24px">
            <NTag type="info">{{ ipsecStatusInfo.templateName }}</NTag>
          </NFormItemGi>
          <NFormItemGi label="保护网段：" class="pr-24px">
            <component :is="networkSegment" v-if="networkSegment !== null" />
          </NFormItemGi>
        </NGrid>
        <div class="m-y-12px text-16px font-bold">量子隧道详情</div>
        <NGrid :cols="2">
          <NFormItemGi label="加密状态：" :span="2" class="pr-24px">
            <template v-if="ipsecStatusInfo.status.State !== null">
              <NTag v-if="ipsecStatusInfo.status.State" type="info">量子加密正常</NTag>
              <NTag v-else type="warning">隧道断开</NTag>
            </template>
          </NFormItemGi>
          <NFormItemGi label="加密流量：" class="pr-24px">
            {{ `${RxBytes}` }}
          </NFormItemGi>
          <NFormItemGi label="解密流量：" class="pr-24px">
            {{ `${TxBytes}` }}
          </NFormItemGi>
        </NGrid>
        <div class="m-y-12px text-16px font-bold">量子密钥状态</div>
        <NGrid :cols="2">
          <NFormItemGi label="密钥使用量：" :span="2" class="pr-24px">0 B</NFormItemGi>
        </NGrid>
      </NForm>
    </NScrollbar>
  </NModal>
</template>

<style lang="scss">
.vpnDetailForm {
  .n-form-item-label__text {
    color: rgba(0, 0, 0, 0.45);
  }
  .n-form-item-blank {
    color: rgba(0, 0, 0, 0.65);
  }
}
</style>
